package src;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * ClickerWebApplet.java
 *
 * Created on 05/10/2011, 1:07:45 PM
 */
import com.turningtech.poll.Poll;
import com.turningtech.poll.PollService;
import com.turningtech.poll.Response;
import com.turningtech.poll.ResponseListener;
import com.turningtech.receiver.Receiver;
import com.turningtech.receiver.ReceiverService;
import com.turningtech.receiver.ResponseCardLibrary;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultListModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.ListCellRenderer;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.jfree.data.category.DefaultCategoryDataset;

/**
 *
 * @author s4206222
 */
public class ClickerWebApplet extends javax.swing.JApplet {

    private Poll poll;
    private ResponseListModel responseListModel = new ResponseListModel();
    private ReceiverListModel receiverListModel = new ReceiverListModel();
    private ReceiverListCellRenderer receiverCellRenderer = new ReceiverListCellRenderer();
    //dataset for poll results graph
    private DefaultCategoryDataset dataset;
    private int responseCount = 0;

    /** Initializes the applet ClickerWebApplet */
    public void init() {

        System.setProperty("apple.laf.useScreenMenuBar", "true");
        ResponseCardLibrary.turnDebuggingOn();

        ResponseCardLibrary.initializeLicense(
                "University of Queensland",
                "24137BBFEEEA9C7F5D65B2432F10F960");
        try {
            java.awt.EventQueue.invokeAndWait(new Runnable() {

                public void run() {
                    initComponents();
                    initAll();
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void initAll() {

        initReceivers();
        initModel();
        if (receiverList.getModel().getSize() > 0) {
            receiverList.setSelectedIndex(0);
        }
        startPollHandler("InvalidResponse");

    }

    private void startPollHandler(String type) {
        //this.responseChart.setDataset((dataset = createDataset()));
        this.responseListModel.clear();
        try {//System.out.println("evt paramString: " + evt.getActionCommand());
            //see if it's an invalid response poll that we're starting
            if (type.equals("InvalidResponse")) {
                String answerRange = "246809";
                poll = PollService.createCorrectPoll(type, answerRange);
            } else {
                poll = PollService.createPoll();
            }
            poll.addResponseListener(new BasicResponseListener());
            Poll.PollingMode pollingMode = (Poll.PollingMode.valueOf(type));
            poll.start(pollingMode);
        } catch (Exception e) {
            showError("Unable to start poll.", e);
        }
    }

    private void initReceivers() {
        try {
            receiverListModel.addAll(ReceiverService.findReceivers());
        } catch (Exception e) {
            showError("Could not initialize receivers.", e);
        }
        dataset = createDataset();
    }

    private void initModel() {
        //responseChart.setDataset(dataset);

        responseList.setModel(responseListModel);
        receiverList.setModel(receiverListModel);
        receiverList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

            public void valueChanged(ListSelectionEvent e) {
                if (e.getValueIsAdjusting()) {
                    return;
                }
                int selection = receiverList.getSelectedIndex();
                try {
                    Receiver receiver = receiverListModel.get(selection);
                    lblChannel.setText(Integer.toString(receiver.getChannel()));
                    lblDescription.setText(receiver.getDescription());
                    lblId.setText(receiver.getId());
                    lblId1.setText(receiver.getVersion());
                } catch (Exception ex) {
                    //ignore
                }

            }
        });
        receiverList.setCellRenderer(receiverCellRenderer);

    }

    /** This method is called from within the init() method to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        receiverPnl = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        receiverList = new javax.swing.JList();
        receiverInfo = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        lblDescription = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        lblChannel = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        lblId = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        lblId1 = new javax.swing.JLabel();
        PollResults = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        responseList = new javax.swing.JList();
        resCount = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();

        jPanel1.setName("jPanel1"); // NOI18N

        receiverPnl.setBorder(javax.swing.BorderFactory.createTitledBorder("Receivers"));
        receiverPnl.setName("receiverPnl"); // NOI18N
        receiverPnl.setPreferredSize(new java.awt.Dimension(350, 50));

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        receiverList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        receiverList.setName("receiverList"); // NOI18N
        jScrollPane1.setViewportView(receiverList);

        javax.swing.GroupLayout receiverPnlLayout = new javax.swing.GroupLayout(receiverPnl);
        receiverPnl.setLayout(receiverPnlLayout);
        receiverPnlLayout.setHorizontalGroup(
            receiverPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 292, Short.MAX_VALUE)
        );
        receiverPnlLayout.setVerticalGroup(
            receiverPnlLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 104, Short.MAX_VALUE)
        );

        receiverInfo.setBorder(javax.swing.BorderFactory.createTitledBorder("Receiver Info"));
        receiverInfo.setName("receiverInfo"); // NOI18N
        receiverInfo.setPreferredSize(new java.awt.Dimension(350, 132));

        jLabel1.setText("Description:");
        jLabel1.setName("jLabel1"); // NOI18N

        lblDescription.setText("N/A");
        lblDescription.setName("lblDescription"); // NOI18N

        jLabel3.setText("Channel:");
        jLabel3.setName("jLabel3"); // NOI18N

        lblChannel.setText("N/A");
        lblChannel.setName("lblChannel"); // NOI18N

        jLabel2.setText("Id:");
        jLabel2.setName("jLabel2"); // NOI18N

        lblId.setText("N/A");
        lblId.setName("lblId"); // NOI18N

        jLabel4.setForeground(new java.awt.Color(204, 0, 0));
        jLabel4.setText("Firmware:");
        jLabel4.setName("jLabel4"); // NOI18N

        lblId1.setText("N/A");
        lblId1.setName("lblId1"); // NOI18N

        javax.swing.GroupLayout receiverInfoLayout = new javax.swing.GroupLayout(receiverInfo);
        receiverInfo.setLayout(receiverInfoLayout);
        receiverInfoLayout.setHorizontalGroup(
            receiverInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, receiverInfoLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(receiverInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(receiverInfoLayout.createSequentialGroup()
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lblChannel, javax.swing.GroupLayout.DEFAULT_SIZE, 155, Short.MAX_VALUE))
                    .addGroup(receiverInfoLayout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(lblDescription, javax.swing.GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(receiverInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel2)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(receiverInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lblId1)
                    .addComponent(lblId))
                .addContainerGap())
        );
        receiverInfoLayout.setVerticalGroup(
            receiverInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(receiverInfoLayout.createSequentialGroup()
                .addGroup(receiverInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblId)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(receiverInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(lblId1)))
            .addGroup(receiverInfoLayout.createSequentialGroup()
                .addGroup(receiverInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblDescription, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(receiverInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblChannel, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3)))
        );

        PollResults.setBorder(javax.swing.BorderFactory.createTitledBorder("Responses"));
        PollResults.setName("PollResults"); // NOI18N
        PollResults.setPreferredSize(new java.awt.Dimension(350, 184));

        jScrollPane2.setName("jScrollPane2"); // NOI18N

        responseList.setName("responseList"); // NOI18N
        jScrollPane2.setViewportView(responseList);

        resCount.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        resCount.setText("Responses:0");
        resCount.setName("resCount"); // NOI18N

        javax.swing.GroupLayout PollResultsLayout = new javax.swing.GroupLayout(PollResults);
        PollResults.setLayout(PollResultsLayout);
        PollResultsLayout.setHorizontalGroup(
            PollResultsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 292, Short.MAX_VALUE)
            .addComponent(resCount, javax.swing.GroupLayout.DEFAULT_SIZE, 292, Short.MAX_VALUE)
        );
        PollResultsLayout.setVerticalGroup(
            PollResultsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(PollResultsLayout.createSequentialGroup()
                .addComponent(resCount)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 103, Short.MAX_VALUE))
        );

        jButton1.setText("Show Responses");
        jButton1.setName("jButton1"); // NOI18N
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 304, Short.MAX_VALUE)
                            .addComponent(receiverPnl, javax.swing.GroupLayout.Alignment.CENTER, javax.swing.GroupLayout.DEFAULT_SIZE, 304, Short.MAX_VALUE)
                            .addComponent(PollResults, javax.swing.GroupLayout.Alignment.CENTER, javax.swing.GroupLayout.DEFAULT_SIZE, 304, Short.MAX_VALUE)))
                    .addComponent(receiverInfo, javax.swing.GroupLayout.DEFAULT_SIZE, 314, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(receiverPnl, javax.swing.GroupLayout.DEFAULT_SIZE, 130, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(receiverInfo, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(PollResults, javax.swing.GroupLayout.DEFAULT_SIZE, 149, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        PollResults.setVisible(false);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        PollResults.setVisible(!PollResults.isVisible());
        receiverInfo.setVisible(!receiverInfo.isVisible());
        receiverPnl.setVisible(!receiverPnl.isVisible());
    }//GEN-LAST:event_jButton1ActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel PollResults;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JLabel lblChannel;
    private javax.swing.JLabel lblDescription;
    private javax.swing.JLabel lblId;
    private javax.swing.JLabel lblId1;
    private javax.swing.JPanel receiverInfo;
    private javax.swing.JList receiverList;
    private javax.swing.JPanel receiverPnl;
    private javax.swing.JLabel resCount;
    private javax.swing.JList responseList;
    // End of variables declaration//GEN-END:variables

    private void initPoll(String evt) {

        //this.responseChart.setDataset((dataset = createDataset()));
        try {
            poll = PollService.createPoll();
            poll.addResponseListener(new BasicResponseListener());
            Poll.PollingMode pollingMode = (Poll.PollingMode.valueOf(evt));
            poll.start(pollingMode);
            //responseChart.setSubtitle(evt + " Polling Open");
        } catch (Exception e) {
            showError("Unable to start poll.", e);
        }
    }

    private void showError(String message, Exception e) {
        JOptionPane.showMessageDialog(null, message + "\n Reason:" + e.getMessage());
    }

    private void showMsg(String message) {
        JOptionPane.showMessageDialog(null, message);
    }

    private DefaultCategoryDataset createDataset() {
        DefaultCategoryDataset newDataset = new DefaultCategoryDataset();
        List<Receiver> receivers = receiverListModel.getReceivers();
        for (Receiver receiver : receivers) {
            for (int i = 0; i < 10; i++) {
                newDataset.addValue(0, receiver.getId(), Integer.toString(i));
            }
        }

        return newDataset;

    }

    private class ReceiverListModel extends DefaultListModel {

        private List<Receiver> receivers = new ArrayList();

        @Override
        public void clear() {
            receivers.clear();
            fireContentsChanged(this, 0, 0);
        }

        public void addAll(Collection newData) {

            receivers.addAll(newData);
            fireContentsChanged(this, 0, 0);
        }

        @Override
        public int getSize() {
            return receivers.size();
        }

        @Override
        public Object getElementAt(int index) {
            return receivers.get(index);
        }

        @Override
        public Receiver get(int index) {
            return receivers.get(index);
        }

        public List<Receiver> getReceivers() {
            return receivers;
        }
    }

    private class ReceiverListCellRenderer extends JLabel implements ListCellRenderer {

        public Component getListCellRendererComponent(JList list, Object value,
                int index, boolean isSelected, boolean cellHasFocus) {

            Receiver r = receiverListModel.get(index);

            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }
            setOpaque(true);
            setText(r.getId());

            return this;
        }
    }

    private class ResponseListModel extends DefaultListModel {

        List<Response> responses = new ArrayList();

        @Override
        public void clear() {
            responses.clear();
            responseCount = 0;
            fireContentsChanged(this, 0, 0);
        }

        public void add(Response newData) {
//            logger.info("response:"+ newData.getResponse());


            responseCount++;
            resCount.setText("Resoponses:" + responseCount++);

            responses.add(newData);
            fireContentsChanged(this, getSize() - 2, getSize() - 1);
        }

        @Override
        public int getSize() {
            return responses.size();
        }

        @Override
        public Object getElementAt(int index) {
            return responses.get(index);
        }
    }

    private class BasicResponseListener implements ResponseListener {

        public BasicResponseListener() {
        }

        public void responseReceived(Response response) {
            responseListModel.add(response);
            if (response.getReceiverId() == null
                    || response.getResponse() == null
                    || response.getResponse().equals("?")) {
                return;
            }

//            if (!dataset.getColumnKeys().contains(response.getResponse()))

            /**
            Number count = dataset.getValue(response.getReceiverId(), response.getResponse());
            if (count == null) {
            count = new Integer(1);
            }
             */
            //dataset.incrementValue(1, response.getReceiverId(), response.getResponse());
        }
    }

    private class SetChannelAction extends AbstractAction {

        public SetChannelAction() {
            putValue(Action.NAME, "Set Channel");
            putValue(Action.LONG_DESCRIPTION, "Set Channel");
        }

        public void actionPerformed(ActionEvent arg0) {
            try {

                int index =
                        receiverList.getSelectionModel().getAnchorSelectionIndex();
                if (index < 0) {
                    return;
                }
                List<Receiver> receivers = receiverListModel.getReceivers();
                Receiver r = receivers.get(index);
                String channel = JOptionPane.showInputDialog("Please enter the new channel:");
                if (channel == null) {
                    return;
                }
                r.setChannel(Integer.parseInt(channel));
                lblChannel.setText(Integer.toString(r.getChannel()));

            } catch (Exception ex) {
                Logger.getLogger(ClickerWebApplet.class.getName()).log(
                        Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(null, "Could not set the channel.");
            }
        }
    }
}
